package com.hua.utility.web;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class CharacterEncodingFilterByServlet implements Filter {

	protected String encoding = null;

	public void init(FilterConfig filterConfig) throws ServletException {
		this.encoding = filterConfig.getInitParameter("encoding");
		if (encoding == null) {
			encoding = "utf-8";
		}
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		response.setContentType("text/html;charset=" + encoding);
		response.setCharacterEncoding(encoding);
		request.setCharacterEncoding(encoding);

		if ("GET".equals(((HttpServletRequest) request).getMethod())) {
			chain.doFilter(new EncodeRequest((HttpServletRequest) request), response);
		} else {
			chain.doFilter(request, response);
		}

	}

	public void destroy() {
		this.encoding = null;
	}

	class EncodeRequest extends HttpServletRequestWrapper {
		private final String[] charsets = { "iso8859-1", "gbk", "gb2312", "gb18030", "utf-8", "ucs" };

		@Override
		public String getParameter(String param) {
			String value = super.getParameter(param);
			return convertCharset(value);
		}

		@Override
		public String[] getParameterValues(String name) {
			String[] values = super.getParameterValues(name);
			if (values == null) {
				return null;
			}
			for (int i = 0; i < values.length; i++) {
				values[i] = convertCharset(values[i]);
			}
			return values;
		}

		@Override
		public Map<String, String[]> getParameterMap() {
			Map<String, String[]> map = super.getParameterMap();
			Map<String, String[]> result = new HashMap<String, String[]>();
			Set<Entry<String, String[]>> entrySet = map.entrySet();
			for (Entry<String, String[]> set : entrySet) {
				String paramName = set.getKey();
				String[] paramValue = set.getValue();
				for (int i = 0; i < paramValue.length; i++) {
					paramValue[i] = convertCharset(paramValue[i]);
				}
				result.put(paramName, paramValue);
			}
			return result;
		}

		public EncodeRequest(HttpServletRequest request) {
			super(request);
		}

		private String convertCharset(String value) {
			String result = value;
			try {
				if (value != null) {
					for (String charset : charsets) {
						if (value.equals(new String(value.getBytes(charset), charset))) {
							result = new String(value.getBytes(charset), encoding);
							break;
						}
					}
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			return result;
		}
	}

}